home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ov143b.zip / OVFILE.C < prev    next >
C/C++ Source or Header  |  1993-01-04  |  26KB  |  779 lines

  1. /*  068  9-Jun-87  ovfile.c
  2.  
  3.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <fcntl.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include "ov.h"
  12. #include "overr.h"
  13. #include "direct.h"
  14. #include "dosfile.h"
  15. #include "strmem.h"
  16.  
  17. static int stowidx;
  18. static FILE_ENT *stowfp;
  19. static DRIVE_ENT *drvlst = NULL;
  20. static char *notitself = "You can't copy a file to itself!";
  21. static char *mustbedir = "Enter a drive and/or directory name!";
  22.  
  23. extern WINDOW cw;
  24. extern int diridx;
  25. extern char **dirlst;
  26. extern FILE_ENT files[];
  27. extern char *cantopen, *none_tagged;
  28.  
  29. DRIVE_ENT *findrive(int);
  30. struct search_block *nxtfile();
  31. char far *largest_f(unsigned int, unsigned int *);
  32. unsigned int readbuf(int,char far *,unsigned int);
  33. unsigned int writebuf(int,char far *,unsigned int);
  34. char *strupr(), *strchr(), *dirplus(FILE_ENT *, char *);
  35. char *parsepath(char *, char *, char *, int, char **, char **);
  36. int free_f(char far *), stowfile(struct search_block *, char *);
  37. int add2windows(char *, char *, FILE_ENT *), delfromwins(char *, char *);
  38.  
  39.  
  40. /******************************************************************************
  41.  **                        G E T F I L E S                                   **
  42.  *****************************************************************************/
  43.  
  44. getfiles() {           /* get data for the files in the current dir */
  45.  
  46.    int firsttime;
  47.    char pathbuf[MAX_PATHLEN+6];
  48.    register struct search_block *sbp;
  49.  
  50.    cw.files_size = 0;                  /* no files yet */
  51.    firsttime = TRUE;                   /* tell nxtfile() its the first call */
  52.  
  53.    stowidx = 0;                        /* start storing at the begining */
  54.    stowfp = files;
  55.  
  56.    /* if showall mode is active, call scantree to get all files, otherwise
  57.       scan the current dir ourselves */
  58.  
  59.    if (cw.showall) {   /* scan the current disk? */
  60.  
  61.       *pathbuf = '\0';
  62.       strncat(pathbuf,cw.dirbuf,2);
  63.       scantree("\\",pathbuf,0x16,stowfile);    /* scan entire disk */
  64.  
  65.    } else        /* scan the current directory */
  66.  
  67.       while (stowidx < MAX_FILES && (sbp = nxtfile("*.*",0x16,&firsttime)))
  68.             stowfile(sbp,NULL);
  69.  
  70.    /* sort the file names if there are any, also set nfiles */
  71.  
  72.    if (cw.nfiles = stowidx)
  73.       sort_files(NULL);
  74.  
  75.    /* set current file pointer to the first file */
  76.  
  77.    cw.curidx = 0;
  78.  
  79.    /* set file counters */
  80.  
  81.    cw.num_files = cw.nfiles;           /* files in the dir */
  82.    cw.num_tagged = 0;                  /* no files tagged yet */
  83.    cw.tag_size = 0;
  84.  
  85. }
  86.  
  87.  
  88. /*****************************************************************************
  89.                              S T O W F I L E
  90.  *****************************************************************************/
  91.  
  92. static int
  93. stowfile(sbp,dirp)     /* store a file in files[] */
  94. register struct search_block *sbp;
  95. char *dirp;
  96. {
  97.    register int len;
  98.    static char *lastdir = NULL;
  99.    register FILE_ENT *fp = stowfp;     /* fast stow pointer */
  100.  
  101.    /* if dirp is not NULL, this call is defining which dir is being scanned,
  102.       add this dir name to the showall dir list - return NZ (keep going) if
  103.       dir name added okay, 0 (stop scanning) if can't add dir name - don't
  104.       incr diridx unless everything is okay.  The dir name passed will always
  105.       have a trailing \ which we don't really want - don't keep it unless
  106.       this happens to be the root dir (len == 3) */
  107.  
  108.    if (dirp) {
  109.       if (diridx < MAX_DIR) {
  110.          len = strlen(dirp);
  111.          dirlst[diridx++] = lastdir = Strndup(dirp,len > 3 ? len-1 : len);
  112.          return(1);
  113.       }
  114.       return(0);
  115.    }
  116.  
  117.    /* ignore . and .. entries.  If the file mask is defined, make
  118.       sure the file name matches.  Make sure the file attributes
  119.       match the selection attributes */
  120.  
  121.    if (stowidx >= MAX_FILES || *sbp->fn == '.' ||
  122.        (cw.selatrs & sbp->attrib) != sbp->attrib ||
  123.        (*cw.mask && (cw.maskcmp != match_name(sbp->fn,cw.mask))))
  124.  
  125.       return(1);       /* don't want this one, but keep looking */
  126.  
  127.    /* we want the file, fill in files[] entry */
  128.  
  129.    fp->size = sbp->size;
  130.    fp->flags = sbp->attrib & 0x3f;
  131.    fp->index = stowidx++;
  132.    fp->date = sbp->date;
  133.    fp->time = sbp->time;
  134.    strcpy(fp->name,sbp->fn);
  135.    fp->dirp = cw.showall ? lastdir : cw.dirbuf;   /* point to files dir str */
  136.    cw.files_size += fp->size;                     /* accumulate total size */
  137.  
  138.    stowfp++;                             /* update for next time */
  139.    return(1);                            /* keep looking */
  140. }
  141.  
  142.  
  143. /******************************************************************************
  144.  **                             I N F O                                      **
  145.  *****************************************************************************/
  146.  
  147. info() {               /* toggle the extended info display */
  148.  
  149.    cw.info_display ^= 1;               /* toggle info on/off */
  150.  
  151.    infocnt(cw.info_display ? 1 : -1);  /* one more or less info window */
  152.  
  153.    adjust_window();                    /* resize the window data */
  154.  
  155.    update_window(1);                   /* display files in new format */
  156. }
  157.  
  158.  
  159. /******************************************************************************
  160.  **                      C O P Y _ C U R R E N T                             **
  161.  *****************************************************************************/
  162.  
  163. copy_current() {       /* copy the current file */
  164.  
  165.    FILE_ENT tmpfent;
  166.    register FILE_ENT *fp;
  167.    register DRIVE_ENT *dp;
  168.    char *dest, *target, *todir, *tofn;
  169.  
  170.    dest = prompt("Copy current file","Copy to where? ",NULL,0,MAX_REPLY);
  171.    if (strlen(dest) == 0)
  172.       return;
  173.  
  174.    fp = &files[cw.curidx];
  175.    target = parsepath(fp->dirp,fp->name,dest,isadir(fp->dirp,dest),&todir,&tofn);
  176.  
  177.    if (strcmp(fp->dirp,todir) != 0 || strcmp(fp->name,tofn) != 0) {
  178.       if (copyfile(fp,target)) {
  179.          tmpfent = *fp;                     /* new file will have */
  180.          tmpfent.flags |= ARCHIVE;          /* ARCHIVE attrib on  */
  181.          add2windows(todir,tofn,&tmpfent);
  182.          dp = findrive(*todir);
  183.          getvolsiz(dp->drive,&dp->vol_size,&dp->vol_free,&dp->clustersiz);
  184.       }
  185.    } else           /* attempt to copy file to itself! */
  186.  
  187.       show_error(0,0,1,notitself);
  188.  
  189.    free(target);
  190.    free(todir);
  191.    free(tofn);
  192. }
  193.  
  194.  
  195. /******************************************************************************
  196.  **                        C O P Y _ T A G G E D                             **
  197.  *****************************************************************************/
  198.  
  199. copy_tagged() {        /* mass copy of tagged files to somewhere */
  200.  
  201.    int i, ch;
  202.    FILE_ENT tmpfent;
  203.    register FILE_ENT *fp;
  204.    register DRIVE_ENT *dp;
  205.    char *dir, *target, *todir, *tofn;
  206.  
  207.    if (cw.num_tagged == 0)             /* are there any tagged files? */
  208.       show_error(0,NONE_TAGGED,1,none_tagged);
  209.  
  210.    dir = prompt("Copy tagged files","Copy to which dir? ",NULL,0,MAX_REPLY);
  211.    if (strlen(dir) == 0)
  212.       return;
  213.  
  214.    if (!isadir(cw.dirbuf,dir))         /* user must give a directory name */
  215.       show_error(0,MUST_BE_DIR,1,mustbedir);
  216.  
  217.    /* Okay, copy the tagged files */
  218.  
  219.    for (fp = files, i = 0; i < cw.nfiles && !brkout(); i++, fp++)
  220.  
  221.       if (fp->flags & TAGGED) {
  222.          disp_msg(2,"Copying ",fp->name);
  223.  
  224.          target = parsepath(fp->dirp,fp->name,dir,1,&todir,&tofn);
  225.  
  226.          if (strcmp(fp->dirp,todir) != 0 || strcmp(fp->name,tofn) != 0) {
  227.  
  228.             if (copyfile(fp,target)) {
  229.                tmpfent = *fp;                     /* new file will have */
  230.                tmpfent.flags |= ARCHIVE;          /* ARCHIVE attrib on  */
  231.                add2windows(todir,tofn,&tmpfent);
  232.             }
  233.  
  234.          } else        /* trying to copy a file to itself */
  235.  
  236.             show_error(0,0,1,notitself);
  237.  
  238.          free(target);                 /* release temp strings */
  239.          free(todir);
  240.          free(tofn);
  241.       }
  242.  
  243.    clr_msg();                          /* clear last copying msg */
  244.  
  245.    /* update volume stats after copy */
  246.  
  247.    dp = strlen(dir) > 1 && dir[1] == ':' ? findrive(*dir) : cw.drivep;
  248.    getvolsiz(dp->drive,&dp->vol_size,&dp->vol_free,&dp->clustersiz);
  249.  
  250. }
  251.  
  252.  
  253. /******************************************************************************
  254.  **                         C O P Y F I L E                                  **
  255.  *****************************************************************************/
  256.  
  257. static int
  258. copyfile(fp,to)        /* copy from to */
  259. register FILE_ENT *fp;
  260. char *to;
  261. {
  262.    char *fn;
  263.    char far *buffer;
  264.    int fd, td, rc = 0;
  265.    unsigned int bufsiz, len;
  266.    static char *copyabort = " -- copy aborted";
  267.  
  268.    /* allocate space for the in memory copy buffer */
  269.  
  270.    buffer = largest_f(63*1024,&bufsiz);  /* get largest possible blk up 2 63k */
  271.    if (bufsiz < 1024) {                  /* give it up if < 1k available */
  272.       if (bufsiz)                        /* release the tiny buffer */
  273.          free_f(buffer);
  274.       show_error(0,0,2,"No free memory to allocate copy buffer",copyabort);
  275.       goto error1;
  276.    }
  277.  
  278.    /* open the from file */
  279.  
  280.    fd = open(fn = fname(fp),O_RDONLY|O_BINARY);
  281.    free(fn);
  282.  
  283.    if (fd == -1) {
  284.       show_error(SHOW_DOS,0,3,cantopen,fp->name,": ");
  285.       goto error2;
  286.    }
  287.  
  288.    /* open the output file */
  289.  
  290.    if ((td = open(to,O_CREAT|O_BINARY|O_TRUNC|O_RDWR,S_IWRITE)) == -1) {
  291.       show_error(SHOW_DOS,0,3,cantopen,to,": ");
  292.       goto error3;
  293.    }
  294.  
  295.    /* copy the file, a buffer at a time */
  296.  
  297.    while (len = readbuf(fd,buffer,bufsiz))
  298.  
  299.      if (writebuf(td,buffer,len) < len) {
  300.          show_error(0,0,3,"Error writting to ",to,": Disk may be full");
  301.          goto error4;
  302.       }
  303.  
  304.    setftime(td,fp->date,fp->time);     /* to file time = from file */
  305.  
  306.    rc = 1;                             /* the copy seems to have worked */
  307.  
  308.    error4: close(td);                  /* close the to file */
  309.  
  310.    if (!rc)                            /* erase to file if there was an */
  311.       unlink(to);                      /*   error while trying to copy  */
  312.  
  313.    error3: close(fd);                  /* close the from file */
  314.    error2: free_f(buffer);             /* release copy buffer */
  315.  
  316.    /* set new file attrib's = old file + ACRHIVE */
  317.  
  318.    if (rc)
  319.       setattrib(to,(fp->flags & (ARCHIVE|SYSTEM|HIDDEN|RDONLY)) | ARCHIVE);
  320.  
  321.    error1: return(rc);                 /* tell caller if we worked */
  322. }
  323.  
  324.  
  325. /******************************************************************************
  326.  **                    E R A S E _ C U R R E N T                             **
  327.  *****************************************************************************/
  328.  
  329. erase_current() {      /* erase the current file */
  330.  
  331.    int ch;
  332.    char askmsg[30];
  333.    register FILE_ENT *fp;
  334.  
  335.    fp = &files[cw.curidx];
  336.  
  337.    strcpy(askmsg,"Erase ");
  338.    strcat(askmsg,fp->name);
  339.    strcat(askmsg," ? (y/N): ");
  340.    ch = ask(askmsg);
  341.  
  342.    if (yes(ch))
  343.       if (delfile(fp)) {                       /* delete the file */
  344.          delfromwins(fp->dirp,fp->name);       /* remove from windows */
  345.          getvolsiz(*cw.dirbuf,&cw.drivep->vol_size, /* vol stats have changed */
  346.             &cw.drivep->vol_free,&cw.drivep->clustersiz);
  347.       }
  348. }
  349.  
  350.  
  351. /*****************************************************************************
  352.                           E R A S E _ T A G G E D
  353.  *****************************************************************************/
  354.  
  355. erase_tagged() {       /* erase the tagged files */
  356.  
  357.    int ch;
  358.    register int i;
  359.    register FILE_ENT *fp;
  360.  
  361.    if (cw.num_tagged == 0)             /* are there any tagged files? */
  362.       show_error(0,NONE_TAGGED,1,none_tagged);
  363.  
  364.    ch = ask("Erase all tagged files? (y/N): ");
  365.    if (!yes(ch))
  366.       return;
  367.  
  368.    /* scan files[] looking for tagged files, when found, delete it */
  369.  
  370.    for (i = 0, fp = files; i < cw.nfiles && !brkout(); i++, fp++)
  371.       if (fp->flags & TAGGED) {
  372.          disp_msg(2,"Erasing ",fp->name);
  373.          if (delfile(fp))
  374.             delfromwins(fp->dirp,fp->name);
  375.       }
  376.  
  377.    clr_msg();                                  /* clear last erasing msg */
  378.  
  379.    getvolsiz(*cw.dirbuf,&cw.drivep->vol_size,  /* volume stats have changed */
  380.       &cw.drivep->vol_free,&cw.drivep->clustersiz);
  381. }
  382.  
  383.  
  384. /*****************************************************************************
  385.                                D E L F I L E
  386.  *****************************************************************************/
  387.  
  388. static int
  389. delfile(fp)            /* delete a file */
  390. register FILE_ENT *fp;
  391. {
  392.    int rc;
  393.    char *fn;
  394.  
  395.    fn = fname(fp);                     /* in case show-all active */
  396.  
  397.    if (fp->flags & DIR)                /* special case if file is a DIR */
  398.       rc = rmdir(fn);                  /* try to remove a directory     */
  399.    else
  400.       rc = unlink(fn);                 /* delete a file                 */
  401.  
  402.    free(fn);
  403.  
  404.    if (rc)                             /* delete okay? */
  405.       show_error(SHOW_DOS,0,3,"Unable to erase ",fp->name,": ");
  406.  
  407.    return(rc == 0);
  408. }
  409.  
  410.  
  411. /******************************************************************************
  412.                               R E N _ C U R
  413.  ******************************************************************************/
  414.  
  415. ren_cur() {            /* rename (or move) the current file */
  416.  
  417.    int rc;
  418.    register FILE_ENT *fp;
  419.    char *newname, fn[MAX_NAMELEN+1];
  420.    static char ptxt[] = "Enter new file name or directory name for ";
  421.    char *fnp, *target, *todir, *tofn, *dirp, pmsg[sizeof(ptxt)+MAX_NAMELEN+1];
  422.  
  423.    fp = &files[cw.curidx];
  424.  
  425.    strcpy(pmsg,ptxt);                          /* build prompt string */
  426.    strcat(pmsg,strcpy(fn,fp->name));
  427.  
  428.    newname = strupr(prompt("Rename current file",pmsg,NULL,0,MAX_REPLY));
  429.    if (strlen(newname) == 0)
  430.       return;
  431.  
  432.    /* figure out the full target name, the dir, and the fn */
  433.  
  434.    rc = isadir(dirp=fp->dirp,newname); /* need to know if this is a dir name */
  435.  
  436.    target = parsepath(dirp,fn,newname,rc,&todir,&tofn);
  437.  
  438.    fnp = fname(fp);                    /* from name */
  439.  
  440.    rc = rename(fnp,target);            /* rename/move it */
  441.  
  442.    if (rc == 0) {                      /* rename okay? */
  443.  
  444.       /* note: fn is a local array instead of a pointer to fp->name because
  445.          add2windows() may shift the entries in files[] around thereby making
  446.          fp->name point to the wrong file - same goes for local dirp */
  447.  
  448.       add2windows(todir,tofn,fp);      /* add to new window(s) */
  449.       delfromwins(dirp,fn);            /* del from old window(s) */
  450.  
  451.    } else              /* unable to rename */
  452.  
  453.       show_error(SHOW_DOS,0,3,"Unable to rename ",fn,": ");
  454.  
  455.    free(target);               /* release temp strings */
  456.    free(todir);
  457.    free(tofn);
  458.    free(fnp);
  459. }
  460.  
  461.  
  462. /******************************************************************************
  463.                               R E N _ T A G
  464.  ******************************************************************************/
  465.  
  466. ren_tag() {            /* rename (move) all tagged files to another dir */
  467.  
  468.    int i, rc;
  469.    register FILE_ENT *fp;
  470.    char *newdir, *fnp, *target, *todir, *dirp, fn[MAX_NAMELEN+1];
  471.  
  472.    if (cw.num_tagged == 0)             /* are there any tagged files? */
  473.       show_error(0,NONE_TAGGED,1,none_tagged);
  474.  
  475.    newdir = strupr(prompt("Move tagged files","Enter new directory name",
  476.             NULL,0,MAX_REPLY));
  477.  
  478.    if (strlen(newdir) == 0)
  479.       return;
  480.  
  481.    /* the name given must be a directory name */
  482.  
  483.    if (!isadir(cw.dirbuf,newdir))
  484.       show_error(0,MUST_BE_DIR,1,mustbedir);
  485.  
  486.    /* Okay, move the tagged files */
  487.  
  488.    for (i = 0, fp = files; i < cw.nfiles && !brkout(); i++, fp++)
  489.  
  490.       if (fp->flags & TAGGED) {                /* this file tagged? */
  491.  
  492.          /* figure out the target names */
  493.  
  494.          dirp = fp->dirp;
  495.          target = parsepath(dirp,strcpy(fn,fp->name),newdir,1,&todir,NULL);
  496.  
  497.          fnp = fname(fp);              /* from name */
  498.          rc = rename(fnp,target);      /* move the file */
  499.  
  500.          if (rc == 0) {                /* move okay? */
  501.  
  502.             /* note: fn is a local array instead of a pointer to fp->name 'cause
  503.             add2windows() may shift the entries in files[] around thereby making
  504.             fp->name point to the wrong file */
  505.  
  506.             add2windows(todir,fn,fp);  /* add to new window(s) */
  507.             delfromwins(dirp,fn);      /* del from old window(s) */
  508.  
  509.          } else        /* error, unable to rename/move this file */
  510.  
  511.             show_error(SHOW_DOS,0,3,"Unable to move ",fn,": ");
  512.  
  513.          free(target);                 /* must be tough on malloc & friends */
  514.          free(todir);
  515.          free(fnp);
  516.       }
  517. }
  518.  
  519.  
  520. /******************************************************************************
  521.                                 L O G I N
  522.  *****************************************************************************/
  523.  
  524.  
  525. login() {              /* login to another directory */
  526.  
  527.    char *new_dir, *todir;
  528.  
  529.    new_dir = prompt(NULL,"Login to which drive/directory? ",NULL,0,MAX_REPLY);
  530.  
  531.    /* if they give a relative dir spec and showall is in effect, we want
  532.       the relative dir spec to be relative to the current file's dir, not
  533.       the current dir */
  534.  
  535.    if (strlen(todir = new_dir)) {
  536.       if (cw.showall && cw.curidx < cw.nfiles)
  537.          parsepath(files[cw.curidx].dirp,"",new_dir,1,&todir,NULL);
  538.  
  539.       switch_dir(todir);
  540.  
  541.       if (todir != new_dir)            /* free mem if parsepath called */
  542.          free(todir);
  543.    }
  544. }
  545.  
  546.  
  547. /******************************************************************************
  548.  **                       S W I T C H _ D I R                                **
  549.  *****************************************************************************/
  550.  
  551. switch_dir(dir)        /* change the current directory */
  552. char *dir;
  553. {
  554.    int rc;
  555.    register DRIVE_ENT *dp;
  556.  
  557.    if ((rc = change_dir(dir)) == 0) {  /* dir switched okay? */
  558.  
  559.       if (cw.showall)                  /* turn off showall mode if it was */
  560.          showoff();                    /*   in effect in this window */
  561.  
  562.       getcwd(cw.dirbuf,MAX_PATHLEN);   /* get the current dir name */
  563.       initdrive(*cw.dirbuf);           /* (re)init DRIVE_ENT for this drive */
  564.       getfiles();                      /* load the files[] structure */
  565.       adjust_window();                 /* resize window data */
  566.       update_header();                 /* update the header  */
  567.       update_window(1);                /* and the window data */
  568.  
  569.    } else {                            /* can't switch, tell user */
  570.  
  571.       show_error(SHOW_DOS,0,3,"Can't change to ",dir,": ");
  572.    }
  573.    return(rc);
  574. }
  575.  
  576.  
  577. /*****************************************************************************
  578.                             I N I T D R I V E
  579.  *****************************************************************************/
  580.  
  581. initdrive(drive)       /* initialize DRIVE_ENT for 'drive' */
  582. int drive;
  583. {
  584.    register DRIVE_ENT *dp;
  585.  
  586.    dp = findrive(*cw.dirbuf);       /* get DRIVE_ENT address 4 drive */
  587.    cw.drivep = dp;                  /* keep address in window block */
  588.  
  589.    get_set_vol(dp->volbuf,NULL);            /* get the new volume name */
  590.    getvolsiz(*cw.dirbuf,&dp->vol_size,      /*  and the volume size stats */
  591.              &dp->vol_free,&dp->clustersiz);/*  incase they are different */
  592.  
  593. }
  594.  
  595.  
  596. /******************************************************************************
  597.                             F I N D R I V E
  598.  *****************************************************************************/
  599.  
  600. DRIVE_ENT *
  601. findrive(drive)        /* find or allocate a DRIVE_ENT for drive */
  602. int drive;
  603. {
  604.    register DRIVE_ENT *dp, *ldp = NULL;
  605.  
  606.    dp = drvlst;                        /* try to find the DRIVE_ENT in the */
  607.    while (dp != NULL) {                /*   linked list of DRIVE_ENTs */
  608.       if (dp->drive == drive)
  609.          break;
  610.       ldp = dp;
  611.       dp = dp->next;
  612.    }
  613.  
  614.    if (dp == NULL) {                   /* allocate a new DRIVE_ENT */
  615.       dp = (DRIVE_ENT *) Malloc(sizeof(DRIVE_ENT));
  616.       dp->next = NULL;
  617.       dp->drive = drive;
  618.       if (ldp)
  619.          ldp->next = dp;
  620.       else
  621.          drvlst = dp;
  622.    }
  623.  
  624.    return(dp);
  625. }
  626.  
  627.  
  628. /*****************************************************************************
  629.                                F I N D I R
  630.  *****************************************************************************/
  631.  
  632. char *
  633. findir(dir)    /* find a dirlst entry that matches dir */
  634. char *dir;
  635. {
  636.    register int i;
  637.    register char **dp;
  638.  
  639.    for (dp = dirlst, i = diridx; i; i--, dp++)
  640.       if (strcmp(dir,*dp) == 0)
  641.          return(*dp);
  642.  
  643.    return("");                 /* better never happen! */
  644. }
  645.  
  646.  
  647. /******************************************************************************
  648.  **                         S E T _ V O L                                    **
  649.  *****************************************************************************/
  650.  
  651. set_vol() {            /* set the volume label */
  652.  
  653.    char *label;
  654.  
  655.    label = prompt("Set volume label","Enter new volume label: ",NULL,0,11);
  656.    if (strlen(label) == 0)
  657.       return;
  658.  
  659.    get_set_vol(cw.drivep->volbuf,label);    /* one call to set it */
  660.    get_set_vol(cw.drivep->volbuf,NULL);     /* another to see what comes back */
  661.  
  662.    gotorc(VOL_ROW,1);                  /* display volume label */
  663.    out_str(cw.drivep->volbuf,11,' ');
  664. }
  665.  
  666.  
  667. /*****************************************************************************
  668.                           M A T C H _ N A M E
  669.  *****************************************************************************/
  670.  
  671. match_name(np,pp)      /* determine if file name matched pattern */
  672. register char *np, *pp;
  673. {
  674.    /* Why you might ask is this code like this, well..., I have plans to port
  675.       this code to a system that has file names up to 79 characters long, and
  676.       I thought this type of code would be easier to port than something that
  677.       knew MS-DOS names are 8+3 */
  678.  
  679.    while (*np) {
  680.       if (*np == *pp)                          /* name char match pattern? */
  681.          goto match;
  682.       else
  683.          if (*np == '.') {                     /* watch to switches to the */
  684.             while (*pp == '*' || *pp == '?')   /* extension, the pattern   */
  685.                pp++;                           /* must have one also */
  686.             if (*pp != '.')
  687.                return(0);                      /* no pattern ext, no match */
  688.             goto match;
  689.          } else
  690.             if (*pp == '*') {                  /* allow wildcards */
  691.                np++;                           /* NOTE: doesn't advance the */
  692.                continue;                       /*       pattern pointer */
  693.             } else
  694.                if (*pp == '?')
  695.                   goto match;
  696.                else
  697.                   return(0);                   /* don't match, not wild */
  698.    match:
  699.       np++;                                    /* chars match, advance */
  700.       pp++;
  701.    }
  702.  
  703.    /* the name string matched so far, make sure the pattern only has
  704.       wildcards left (if anything) */
  705.  
  706.    while (*pp)
  707.       if (*pp != '*' && *pp != '?' && *pp != '.')
  708.          return(0);
  709.       else
  710.         pp++;
  711.  
  712.    return(1);                          /* A MATCH! */
  713. }
  714.  
  715.  
  716. /*****************************************************************************
  717.                            P A C K F I L E S
  718.  *****************************************************************************/
  719.  
  720. packfiles() {          /* pack the files structure */
  721.  
  722.    FILE_ENT *endp;
  723.    register FILE_ENT *p, *q;
  724.  
  725.    p = q = files;
  726.    endp = &files[cw.nfiles];
  727.  
  728.    while (q < endp)
  729.       if (*p->name) {
  730.          if (p == q)
  731.             p = ++q;
  732.          else
  733.             p++;
  734.       } else
  735.          if (*q->name == '\0')
  736.             q++;
  737.          else {
  738.             *p++ = *q;
  739.             *q->name = '\0';
  740.             q++;
  741.          }
  742.  
  743.    cw.nfiles = p - files;              /* new # of files in files[] */
  744. }
  745.  
  746.  
  747. /*****************************************************************************
  748.                                 F N A M E
  749.  *****************************************************************************/
  750.  
  751. char * ALTCALL
  752. fname(fp)              /* return the address of a file name */
  753. register FILE_ENT *fp;
  754. {
  755.    return(dirplus(fp,fp->name));       /* maybe this routine is too simple */
  756. }
  757.  
  758. /*****************************************************************************
  759.                              D I R P L U S
  760.  *****************************************************************************/
  761.  
  762. char *
  763. dirplus(fp,pp)         /* return a string which is the files dir + whatever */
  764. register FILE_ENT *fp;
  765. char *pp;
  766. {
  767.    register char *dp;
  768.  
  769.    if (cw.showall) {
  770.       dp = (char *) Malloc(strlen(fp->dirp)+strlen(pp)+2);
  771.       strcpy(dp,fp->dirp);
  772.       if (dp[strlen(dp)-1] != '\\')
  773.          strcat(dp,"\\");
  774.       strcat(dp,pp);
  775.       return(dp);
  776.    } else
  777.       return(Strdup(pp));
  778. }
  779.